/*

Copyright (C) 2007 Thomas Geiger (tom.geiger@gmail.com)

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/

// Author: Thomas Geiger
// Proxy support by Manfred Gschweidl (manfred.gschweidl@students.fhv.at)

#ifndef CREDMGR_H_
#define CREDMGR_H_

#include <iostream>
#include <string>
#include <sstream>
#include "globus_gss_assist.h"
#include "globus_gsi_system_config.h"
#include "globus_gsi_proxy.h"
#include "globus_gsi_credential.h"
#include "globus_openssl.h"
#include "myproxy.h"
//#include "ssl_utils.h"

using namespace std;

namespace globus_common {

/**
 * The Credential Manager class encapsulates the major GSI security 
 * mechanisms. 
 * 
 * Features: 
 * - information for local certificates
 * - management of local and remote (using MyProxy) proxy certificates
 * - acquiring of security contexts 
 * 
 */
class CredManager
{
	private:
		//variables
		//return codes
		OM_uint32							major_status;
		OM_uint32							minor_status;
		//handles
		gss_cred_id_t						handle;
		globus_gsi_proxy_handle_t           proxy_handle;
	    globus_gsi_proxy_handle_attrs_t     proxy_handle_attrs;
	    globus_gsi_callback_data_t          callback_data;
	    globus_gsi_cred_handle_attrs_t      cred_handle_attrs;
	    globus_gsi_cred_handle_t            cred_handle;
	    globus_gsi_cred_handle_t            proxy_cred_handle;
	    globus_gsi_cert_utils_cert_type_t   cert_type;
	    
	    X509_NAME* 							subject_name;
		char*								user_cert_filename;
		char*								user_key_filename;
		char*								proxy_out_filename;
		string								key_password;
		int									key_bits;
		int									valid;
		time_t								lifetime;
		time_t								goodtill;
		//functions for handling password authentication
	    int pwStdinCallback();
	    static int staticPWStdinCallback(char * buf, int num, int w);		
		//myproxy
		int readMyProxyPassphrase(char *buffer, const int buffer_len);
				
	    //functions
	   	
	    void getProxyOutFile();
	    void destroyCredential();
	    void destroyProxy();
	    void destroyCredentialHandle(globus_gsi_cred_handle_t handle);
	    bool destroyProxyFile();
	    bool initCredentialAttributes();
	    bool destroyCredentialAttributes();
	    bool initCredential();
	    bool readCredentialCert();
	    bool readCredentialKey();
	    void createProxy();	    
	    void verifyProxy();
	    void writeProxy();
	    void readCredentialLifetime();
	    void readCredentialGoodTill();
	    void initProxyAttributes();
	    void checkCredentialLifetime();
	    void destroyProxyAttributes();
	    void setProxyCertificateLifetime();
	    void setProxyCertificateType();
	    void initProxy();
	    void setCertificateType();
	    void readCredentialX509SubjectName();

		//helper functions
		void trimSpaces( string& str);	
		bool test_error(int);
	    string getCertificateType(globus_gsi_cert_utils_cert_type_t cert_type);
	    string getKeyPassword();
	public:
		/**
		 * Constructor
		 */
		CredManager();
		/**
		 * Desctructor
		 */
		virtual ~CredManager();
		
		bool getUserCertFile();
		/**
		 * Returns true when a valid credential is available
		 */
		bool hasCredential();
		/**
		 * Returns true if a proxy cerficiate is available
		 */
		bool hasUserProxy();
		/**
		 * Initialize local proxy certificate
		 */
		bool acquireCredential(string pass);
		/**
		 * Initialize proxy certificate using a MyProxy server
		 */
		bool acquireCredentialMyProxy(string myproxyServer, string pass);
		/**
		 * Delete proxy credential
		 */
		bool releaseCredential();
		/**
		 * Display information regarding the certificate
		 */
		string printCertificateSubject();
		/**
		 * Display information regarding the proxy certificate
		 */
		string printProxySubject();
		/**
		 * Returns a certificate handle
		 */
		static bool acquireCredential(gss_cred_id_t &);
		/**
		 * Releases a certificate handle
		 */
		static bool releaseCredential(gss_cred_id_t &);
};

}

#endif /*CREDMGR_H_*/
